#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include<string>
#include <bitset>
#include <limits>
#include <QDateTime>
#include <QTextCodec>

#include <opencv.hpp>
using namespace std;
using namespace cv;
//最左边是第一位
string ChangeTo2Left(unsigned long long flag)
{
    string str="";
    char temp[2];
    unsigned long long mask = 1;
    int tempFlag=0;
    for(int i=0;i<64;++i)
    {
        tempFlag=(flag>>i) & mask;
        str.append(temp);
    }
    return str;
}
//最右边是第一位
string ChangeTo2Right(unsigned long long flag)
{
    string str="";
    char temp[2];
    unsigned long long mask = 1;
    int tempFlag=0;
    for(int i=0;i<64;++i)
    {
        tempFlag=(flag>>i) & mask;
        str.insert(0,temp);
    }
    return str;
}
/*!
 * \brief m_maxGuid 初始化时间
 */
static unsigned long long m_startTime;
/*!
 * \brief m_sequence
 */
static int m_maxSequence=0;
/*!
 * \brief initGuid 初始化
 */
void initGuid()
{
    m_startTime=QDateTime::currentDateTime().currentMSecsSinceEpoch();
    m_startTime<<=32;
    m_maxSequence=0;
}
/*!
 * \brief newGuid
 * \param sequence
 * \return
 */
unsigned long long newGuid()
{
    m_maxSequence++;
    return m_startTime | m_maxSequence;
}
/*!
 * \brief getDateTime 获取时间
 * \param guid
 * \return
 */
unsigned long getDateTime(unsigned long long guid)
{
    return (guid & 0xFFFFFFFF00000000)>>32;
}
/*!
 * \brief getSequence 获取序号
 * \param guid
 * \return
 */
unsigned long getSequence(unsigned long long guid)
{
    return (guid & 0x00000000FFFFFFFF);
}
void testCamera()
{
    cvNamedWindow("DisplayCamera", CV_WINDOW_AUTOSIZE);
    CvCapture* capture = cvCreateCameraCapture(0);
    IplImage* frame;

    const char filename[] = "video.avi";

    //  int fourcc = CV_FOURCC('X','V','I','D');
    //  int fourcc = CV_FOURCC('P','I','M','1');
    int fourcc = CV_FOURCC('M','J','P','G');
    //  int fourcc = CV_FOURCC('M', 'P', '4', '2');
    //  int fourcc = CV_FOURCC('D', 'I', 'V', '3');
    //  int fourcc = CV_FOURCC('D', 'I', 'V', 'X');
    //  int fourcc = CV_FOURCC('U', '2', '6', '3');
    //  int fourcc = CV_FOURCC('I', '2', '6', '3');
    //  int fourcc = CV_FOURCC('F', 'L', 'V', '1');
    //  fourcc = -1;
    //  int fourcc = 0;

    //  printf("%d\n", fourcc);

    double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
    int width = (int) cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH );
    int height = (int) cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT );
    CvSize size = cvSize( width , height );
    int isColor = 1;
    CvVideoWriter* writer = cvCreateVideoWriter(filename, fourcc, fps, size, isColor);

    while(1)
    {
        frame = cvQueryFrame( capture );
        if( !frame )
        {
            fprintf(stderr,"Frame error");
            break;
        }

        cvWriteFrame(writer , frame);
        cvShowImage("DisplayCamera", frame);

        char c = cvWaitKey( 30 );
        if( c == 27 ) break;
    }

    cvReleaseVideoWriter(&writer);
    cvReleaseImage(&frame);
    cvReleaseCapture(&capture);
    cvDestroyWindow("DisplayCamera");
}
void testCamera2()
{
    VideoCapture vcap(0);
    if(!vcap.isOpened()){
        cout << "Error opening video stream or file" << endl;
        return;
    }

    double fps =  vcap.get(CV_CAP_PROP_FPS);
    int frame_width=   vcap.get(CV_CAP_PROP_FRAME_WIDTH);
    int frame_height=   vcap.get(CV_CAP_PROP_FRAME_HEIGHT);
    VideoWriter video("out.avi",CV_FOURCC('M','J','P','G'),fps, Size(frame_width,frame_height),true);

    for(;;){

        Mat frame;
        vcap >> frame;
        video.write(frame);
        imshow( "Frame", frame );
        char c = (char)waitKey(33);
        if( c == 27 ) break;
    }
}

void testDisplacement()
{
    initGuid();
    unsigned long long id=0;
    unsigned long startTime=0;
    unsigned long sequence=0;
    for(int i=0;i<1;i++){
        id=newGuid();
        startTime=getDateTime(id);
        sequence=getSequence(id);
        cout<<hex<<"Id         = "<<id<<endl;
        cout<<hex<<"DateTimeId = "<<startTime<<endl;
        cout<<hex<<"Sequence   = "<<sequence<<endl;
        cout <<"Id         = "<<bitset<sizeof(unsigned long long)*8>(id)<<endl;
        cout <<"DateTimeId = "<<bitset<sizeof(unsigned long)*8>(startTime)<<endl;
        cout <<"Sequence   =                                 "<<bitset<sizeof(unsigned long)*8>(sequence)<<endl;
    }
    QDateTime dt=QDateTime::fromMSecsSinceEpoch(4294967296-startTime);
    cout<<dec<<dt.date().year()<<endl;
}
void testCanny()
{
    VideoCapture vcap(0);
    if(!vcap.isOpened()){
        cout << "Error opening video stream or file" << endl;
        return;
    }
    Mat src, dst, color_dst;
    vcap>>src;
    Canny( src, src, 50, 200, 3 );
    cvtColor( dst, color_dst, COLOR_GRAY2BGR );
    imshow( "Frame", color_dst );
    waitKey(0);
}
Mat src; Mat src_gray;
int thresh = 100;
int max_thresh = 255;
RNG rng(12345);

/// Function header
void thresh_callback(int, void* );
void testFindContours()
{
    // the first command-line parameter must be a filename of the binary
    // (black-n-white) image
    src=cvLoadImage("D:/SWT_OUT/TestPicture/1/das.jpg");
    if(!(src).data)
        return;
    /// Convert image to gray and blur it
    cvtColor( src, src_gray, CV_BGR2GRAY );
    blur( src_gray, src_gray, Size(3,3) );

    /// Create Window
    char* source_window = "Source";
    namedWindow( source_window, CV_WINDOW_AUTOSIZE );
    imshow( source_window, src );

    createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
    thresh_callback( 0, 0 );

    waitKey(0);
}
/** @function thresh_callback */
void thresh_callback(int, void* )
{
  Mat canny_output;
  vector<vector<Point> > contours;
  vector<Vec4i> hierarchy;

  /// Detect edges using canny
  Canny( src_gray, canny_output, thresh, thresh*2, 3 );
  /// Find contours
  findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

  /// Draw contours
  Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
  for( int i = 0; i< contours.size(); i++ )
     {
       Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
       drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
     }

  /// Show in a window
  namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
  imshow( "Contours", drawing );
}
int main()
{
    testFindContours();
    return 0;
}

